#include <iostream>
#include <pthread.h>
#include <string>
#include <time.h>
#include <unistd.h>
#include <functional>
#include <vector>

using namespace std;


// 证明线程局部存储
// __thread int g_val = 100;

// // 新线程
// void *ThreadRoutine(void *arg)
// {
//     while (1)
//     {
//         cout << "I am new thread" << ", pid : " << getpid() << " , g_val : " << g_val << " ,&g_val" << &g_val << endl;
//         g_val++;
//         sleep(1);
//     }
//     return nullptr;
// }

// int main()
// {
//     // 到这里就已经有进程了
//     pthread_t pth1;
//     pthread_create(&pth1, nullptr, ThreadRoutine, nullptr);
//     sleep(1);

//     // 创建新进程以后，执行main函数的执行流我们叫做主线程
//     while (1)
//     {
//         cout << "I am main thread" << ", pid : " << getpid() << " , g_val : " << g_val << " ,&g_val" << &g_val << endl;
//         sleep(1);
//     }
//     return 0;
// }

// 测试线程ID
// const int threadnum = 3;

// string ToHex(int num)
// {
//     char tmp[64];
//     snprintf(tmp,sizeof(tmp),"0x%x",num);
//     return tmp;
// }

// // 新线程
// void *ThreadRoutine(void *arg)
// {
    
//     string threadname = (char*)arg;
//     while (1)
//     {
//         cout << "I am new thread" << ", pid : " << getpid() << " , " << threadname << endl;
//         sleep(1);
//     }
//     return nullptr;
// }

// int main()
// {
//     vector<pthread_t> pthreads;
//     for (int i = 1; i <= threadnum; i++)
//     {
//         char threadname[64];
//         snprintf(threadname,sizeof(threadname),"%s-%d","thread",i);

//         pthread_t pth;
//         pthread_create(&pth, nullptr, ThreadRoutine, threadname);
//         pthreads.push_back(pth);
//         sleep(1);
//     }

//     for(const auto &pid : pthreads)
//     {
//         cout << pid << "  ";
//     }
//     cout << endl;

//     for(const auto &pid : pthreads)
//     {
//         cout << ToHex(pid) << "  ";
//     }
//     cout << endl;

//     // 创建新进程以后，执行main函数的执行流我们叫做主线程
//     while (1)
//     {
//         cout << "I am main thread" << endl;
//         sleep(1);
//     }

//     return 0;
// }


// 测试线程状态是否影响线程的取消，并测试是否能够等待
// // 新线程
// void *ThreadRoutine(void *arg)
// {
//     const char *threadname = (const char *)arg;
//     while (1)
//     {
//         cout << "I am new thread" << ", pid : " << getpid() << " , " << threadname << endl;
//         sleep(1);
//     }
//     pthread_exit(nullptr);
//     // return nullptr;
// }

// int main()
// {
//     // 到这里就已经有进程了
//     pthread_t pth;
//     pthread_create(&pth, nullptr, ThreadRoutine, (void *)"thread 1");
//     sleep(1);
//     // 创建新进程以后，执行main函数的执行流我们叫做主线程

//     // pthread_detach(pth);

//     int n = pthread_cancel(pth);
//     cout << "get cancel return value : " << n << endl;

//     void *ret = nullptr;
//     n = pthread_join(pth, &ret);
//     cout << "get join return value : " << n << " , thread return " << (int64_t)ret <<endl;

//     while (1)
//     {
//         cout << "I am main thread" << ", pid : " << getpid() << endl;
//         sleep(1);
//     }

//     return 0;
// }

// 测试pthread_join、pthread_exit等函数
// class ReturnDate
// {
// public:
//     ReturnDate(const string& threadname , const string &returnInfo , int code )
//         :_threadname(threadname)
//         ,_returnInfo(returnInfo)
//         ,_code(code)
//         {}
// public:
//     string _threadname;
//     string _returnInfo;
//     int _code;
// };

// // 新线程
// void *ThreadRoutine(void *arg)
// {
//     int cnt = 5;
//     const char *threadname = (const char *)arg;
//     ReturnDate *rdate = new ReturnDate(threadname, "return normal", 520);
//     while (cnt)
//     {
//         cout << "I am new thread" << ", pid : " << getpid() << " , " << threadname << endl;
//         sleep(1);
//         cnt--;
//     }
//     pthread_exit(rdate);
//     // return nullptr;
// }

// int main()
// {
//     // 到这里就已经有进程了
//     pthread_t pth;
//     pthread_create(&pth, nullptr, ThreadRoutine, (void *)"thread 1");
//     sleep(1);
//     // 创建新进程以后，执行main函数的执行流我们叫做主线程
//     void *ret = nullptr;
//     pthread_join(pth, &ret);
//     ReturnDate *rd = (ReturnDate *)ret;
//     cout << "main thread get new thread info -> ";
//     cout << "threadname : " << rd->_threadname << ",returnInfo : " << rd->_returnInfo << ", code : " << rd->_code << endl;

//     while (1)
//     {
//         cout << "I am main thread" << ", pid : " << getpid() << endl;
//         sleep(1);
//     }
//     return 0;
// }

// 创建多个线程

// const int threadnum = 4;

// typedef function<void()> func_t;

// class ThreadDate
// {
// public:
//     ThreadDate(string name, uint64_t time, func_t f)
//         : threadname(name), ctime(time), func(f)
//     {}

// public:
//     string threadname;
//     uint64_t ctime;
//     func_t func;
// };

// void Func()
// {
//     cout << "我完成了部分任务" << endl;
// }

// // 新线程
// void *ThreadRoutine(void *arg)
// {
//     ThreadDate* pt = (ThreadDate*)arg;
//     int a = 10;
//     while (1)
//     {
//         cout << "I am new thread" << " threadname : " << pt->threadname << " create time : " << pt->ctime << endl;
//         // pt->func();
//         sleep(1);
//         if(pt->threadname == "thread-3")
//         {
//             a /= 0;  // 这里故意制造除0错误
//             cout << "发生除0错误啦!!!" << endl;
//         }
//     }
//     return nullptr;
// }

// int main()
// {
//     vector<pthread_t> pthreads;
//     for (int i = 0; i <= threadnum; i++)
//     {
//         char threadname[64];
//         snprintf(threadname,sizeof(threadname),"%s-%d","thread",i);

//         pthread_t pth;
//         ThreadDate* pt = new ThreadDate(threadname,time(nullptr),Func);
//         pthread_create(&pth, nullptr, ThreadRoutine, pt);
//         sleep(1);
//     }

//     // 创建新进程以后，执行main函数的执行流我们叫做主线程
//     while (1)
//     {
//         cout << "I am main thread" << endl;
//         sleep(1);
//     }

//     return 0;
// }